<template>
    <editor :init="tinymceInit" v-model="content" tinymce-script-src="/tinymce/tinymce.min.js" :disabled="disabled" />
</template>
  
<script setup>
/**
 * TinyMCE 富文本编辑器
 * @demo <editor-input v-model:value="dataOfForm.content" />
 * npm install --save tinymce @tinymce/tinymce-vue@^4
 * @link https://github.com/tinymce/tinymce-vue
 * @link https://www.tiny.cloud/get-tiny/self-hosted/
 * @link https://github.com/tinymce/tinymce-vue/issues/30#issuecomment-497005781
 * @link https://www.tiny.cloud/docs/tinymce/6/vue-cloud/
 * @link https://www.tiny.cloud/get-tiny/language-packages/
 * @link https://blog.csdn.net/wp456789/article/details/123042267
 * @link https://zhuanlan.zhihu.com/p/435275506
 * @link https://blog.csdn.net/zfw_666666/article/details/126287239
 * @link https://www.wangeditor.com/
 */

import { ref, watch } from 'vue';
import Editor from '@tinymce/tinymce-vue'
import axios from 'axios';

const tinymceInit = {
    language_url: "/tinymce/langs/zh-Hans.js", // 指定中文包
    language: "zh-Hans", // 中文
    //   skin_url: '/tinymce/skins/ui/oxide', // 编辑器皮肤
    height: 500,// 高度
    browser_spellcheck: true, // 拼写检查
    branding: false, // 去水印，隐藏右下角技术支持
    //   elementpath: false, // 禁用编辑器底部的状态栏
    //   statusbar: false, // 隐藏编辑器底部的状态栏
    paste_data_images: true, // 允许粘贴图像
    menubar: false, // 隐藏最上方menu
    fontsize_formats: ['12px', '14px', '16px', '18px', '24px', '30px', '36px', '48px', '56px', '72px'],
    plugins: 'code preview fullscreen searchreplace save autosave link autolink image media table codesample lists advlist charmap emoticons anchor directionality pagebreak quickbars nonbreaking visualblocks visualchars wordcount',
    toolbar: 'fullscreen preview code | undo redo | copy cut paste remove | forecolor backcolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | formatselect fontselect fontsizeselect | link image media emoticons charmap anchor pagebreak codesample | ltr rtl',
    file_picker_types: 'file image media',
    //自定义文件选择器的回调内容
    images_upload_handler: (blobInfo, success, error) => {
        let file = blobInfo.blob();
        // 使用axios上传
        const formData = new FormData();
        formData.append('file', file, file.name);
        axios.post('/upload/uploadImage', formData).then(res => {
            if (res.data.errcode) {
                error(res.data.message);
            } else {
                success(res.data.data);
            }
        }).catch(e => {
            console.error(e);
            error(e.message);
        });
    },
    // 附件上传
    file_picker_callback: (callback, value, meta) => {
        //文件分类
        var filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4';
        //为不同插件指定文件类型及后端地址
        switch (meta.filetype) {
            case 'image':
                filetype = '.jpg, .jpeg, .png, .gif';
                break;
            case 'media':
                filetype = '.mp3, .mp4';
                break;
            case 'file':
                break;
            default:
                break;
        }
        //模拟出一个input用于添加本地文件
        var input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', filetype);
        input.click();
        let _this = this;
        input.onchange = function () {
            var file = this.files[0];
            // 使用axios上传
            const formData = new FormData();
            formData.append('file', file, file.name);
            _axios.post('/upload/uploadFile', formData).then(res => {
                if (res.data.errcode) {
                    _this.$message.error(res.data.msg);
                    return;
                }
                let filePath = res.data.data.filePath, fileName = res.data.data.fileName;
                switch (meta.filetype) {
                    case 'image':
                        callback(filePath, { alt: fileName });
                        break;
                    case 'media':
                        callback(filePath, { source2: 'alt.ogg', poster: 'image.jpg' });
                        break;
                    case 'file':
                        callback(filePath, { text: fileName });
                        break;
                    default:
                        break;
                }
            }).catch(e => {
                console.error(e);
                _this.$message.error(e.message);
            });
        }
    }
};

const emit = defineEmits(['update:value']);
const props = defineProps({
    value: {
        type: String,
        default: '',
    },
    disabled: {
        type: Boolean,
        default: false
    }
})
const content = ref('');
watch(() => props.value, (newVal) => {
    console.log('watch-value', newVal);
    content.value = newVal;
})
watch(content, (newVal) => {
    console.log('watch-content', newVal);
    emit('update:value', newVal);
})
</script>